home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_7_2.arc / MEMMOVE.ASM < prev    next >
Assembly Source File  |  1989-01-31  |  4KB  |  196 lines

  1. ; a fast MEMMOVE routine that uses the 80836 if present
  2. ; this function can replace the memmove routine supplied with
  3. ; Microsoft and Borland C runtime libraries (sample coded in
  4. ; (small model)
  5. ;
  6. ; Author:        M. Steven Baker
  7. ; Date:            January 19, 1989
  8. ; Last Revision:    January 31, 1989
  9. ;
  10. ;    added test to force word alignment of source
  11.  
  12. ; PROCEDURE cputype
  13. ;
  14. ; find out if we have an 80386 CPU to use
  15. ; This routine can be used from the real or virtual
  16. ; 8086 mode only.  Otherwise will likely cause a
  17. ; protection violation (PUSHF instruction is
  18. ; privileged)
  19. ;
  20. ; Based on COMPAQ DESKPRO 386/20 Technical Reference Guide
  21. ; (originally suggested by INTEL)
  22. ;
  23. ; Entry:    none
  24. ; Exit:        AX = CPU type
  25. ;            0086h if 8088/8086
  26. ;            0286h if 80286
  27. ;            0386h if 80386
  28. ; Stack:    8 bytes
  29. ;
  30.     .MODEL small
  31.     .CODE
  32.  
  33.     public    _cputype
  34.  
  35. _cputype    proc near
  36.     pushf            ;save the real flags register
  37. ;
  38.     pop    ax        ;get register off stack
  39.     push    ax        ;and save it again
  40. ;
  41.     and    ax,0fffh    ;zero out bits 12-15
  42.     push    ax
  43.     popf            ;try to put into flags
  44.     pushf    
  45.     pop    ax        ;let's see what came out
  46.                 ;of flags
  47.     and    ax,0F000h    ;mask off bits 12-15
  48.     cmp    ax,0F000h    ;were these bits all 1's
  49.     je    is_86        ;if so, it's an 8086
  50. ;
  51.     pop    ax        ;get flags register to AX
  52.     push    ax        ;and save it again
  53. ;
  54.     or    ax,0F000h    ;now try to set bits 12-15
  55.     push    ax
  56.     popf            ;of the flags register
  57.     pushf
  58.     pop    ax        ;and see what came out
  59.     and    ax,0F000h    ;are high bits set
  60.     je    is_286        ;if so, we have a 386
  61. is_386:    mov    ax,0386h
  62.     jmp    short    cpu_exit
  63. ;
  64. is_286:    mov    ax,0286h
  65.     jmp    short    cpu_exit
  66. ;
  67. is_86:    mov    ax,86h
  68. ;
  69. cpu_exit:
  70.     popf            ;restore flags
  71.     ret
  72. _cputype    endp    
  73. ;
  74.  
  75. ; PROCEDURE memmove
  76. ;
  77. ; void * memmove(void *dest,const void *src,size_t count);
  78. ; returns *dest
  79.  
  80.     public    _memmove
  81.  
  82. _memmove    proc near
  83.     push    bp        
  84.     mov    bp,sp        ;use BP to get variables
  85.     mov    dx,di        ;save register variables
  86.     mov    bx,si        ;into BX and DX
  87.     mov    ax,ds
  88.     mov    es,ax        ;force ES to DS (small model
  89.     mov    di,[bp+4]    ;get destination ptr
  90.     mov    si,[bp+6]    ;and source ptr
  91.     mov    cx,[bp+8]    ;and byte count
  92. ;
  93.     mov    ax,di        ;memmove returns dest ptr
  94.     jcxz    mmov_ret    ;if count=0, where done
  95. ;
  96.     cmp    di,si        ;do we have possible overlap
  97.     jb    forward1    ;if not go do it
  98. ;
  99.     je    mmov_ret    ;if dest=src, then do nothing
  100.     mov    ax,si        ;
  101.     add    ax,cx        ;find end point of source
  102.     cmp    di,ax        ;do we overlap with dest ?
  103.     mov    ax,di        ;memmove must return dest ptr
  104.     jae    forward        ;no overlap
  105. ;
  106.     add    si,cx        ;copy from end of string back
  107.     add    di,cx
  108.     std            ;set reverse direction
  109.     dec    si
  110.     dec    di
  111. ;
  112.     test    si,1        ;are we at least word aligned?
  113.     jz    back1
  114.     movsb            ;get word aligned    
  115.     dec    cx
  116. ;
  117. back1:    shr    cx,1        ;convert to words
  118.     jnc    back2        ;carry if odd count
  119.     movsb
  120. back2:    dec    si        ;set index for word
  121.     dec    di
  122.     shr    cx,1
  123. patch_o1:
  124.     jnc    back4
  125.     movsw
  126. back4:    sub    di,2
  127.     sub    si,2
  128.     db    66h        ;operand size [refix
  129. patch_i1:
  130.     rep    movsw
  131.     cld            ;force forward direction
  132. mmov_ret:
  133.     mov    si,bx        ;restore register variables
  134.     mov    di,dx
  135.     pop    bp
  136.     ret
  137. forward1:
  138.     test    si,1        ;are we at least word aligned?
  139.     jz    forward
  140.     movsb            ;get word aligned    
  141.     dec    cx
  142. forward:
  143.     shr    cx,1        ;byte count to words
  144.     jnc    forwd4        ;if no carry, then even count
  145.     movsb
  146. forwd4: shr    cx,1        ;word count to dwords
  147. patch_o2:
  148.     db    66h        ;operand size prefix
  149.     rep    movsw        ;(rep movsd) move double words
  150.     adc    cx,cx        ;if carry was odd
  151.     rep    movsw        ;if CX<>0 movsw
  152. ;
  153.     mov    si,bx        ;restore register variables
  154.     mov    di,dx
  155.     pop    bp
  156.     ret
  157. _memmove    endp
  158.  
  159.     public    _cpupatch
  160.  
  161. _cpupatch    proc near
  162.     call    _cputype
  163.     cmp    ax,0386h
  164.     jne    patch_mmove
  165.     ret
  166. ;
  167. patch_mmove:
  168.     push    ds        ;save registers
  169.     push    es    
  170.     push    si
  171.     push    di
  172.     push    cx
  173. ;
  174.     mov    ax,cs        ;set DS=ES to CS
  175.     mov    ds,ax
  176.     mov    es,ax
  177.     mov    si,offset patch_i1    ;input patch
  178.     mov    di,offset patch_o1
  179.     mov    cx,(offset forward- offset patch_i1)
  180.     rep    movsb
  181. ;
  182.     mov    si,offset patch_i1
  183.     mov    di,offset patch_o2
  184.     mov    cx,(offset forward - offset patch_i1)
  185.     rep    movsb
  186. ;
  187.     pop    cx
  188.     pop    di
  189.     pop    si
  190.     pop    es
  191.     pop    ds
  192.     ret
  193.  
  194. _cpupatch    endp
  195.  
  196. end